#ifndef PROTOCOL_H
#define PROTOCOL_H

#include <stdint.h>
#include <stddef.h>

// 协议版本
#define PROTOCOL_VERSION 0x01

// -- 内部协议处理函数返回值 --
#define PROT_SUCCESS 0                        // 操作成功
#define PROT_ERR_GENERIC_ERROR -1             // 通用错误
#define PROT_ERR_VERSION_MISMATCH -2          // 协议版本不匹配
#define PROT_ERR_MALLOC_FAILED -3             // 内存分配失败
#define PROT_ERR_CRC_MISMATCH -4              // CRC32校验失败
#define PROT_ERR_CONNECTION_CLOSED_BY_PEER -5 // 连接被对方关闭 (recv 返回 0)
#define PROT_ERR_SERVER_SENT_ERROR_MSG -6     // 服务器返回了一个标准的错误消息 (MSG_TYPE_ERROR)
#define PROT_ERR_UNEXPECTED_MSG_TYPE -7       // 收到的消息类型与预期的不符 (且不是 MSG_TYPE_ERROR)
#define PROT_ERR_SEQ_NUM_MISMATCH -8          // 收到的序列号与预期的不符
#define PROT_ERR_SEND_FAILED -9               // 发送失败
#define PROT_ERR_RECV_TIMEOUT_WOULD_BLOCK -10 // 接收超时或在非阻塞模式下会阻塞
#define PROT_ERR_INVALID_PARAMS -11           // 函数参数无效
#define PROT_ERR_MSG_TOO_SHORT -12            // 接收到的消息数据过短

// 定义允许的最大消息体长度，例如4MB
// 这个值需要根据实际需求和系统资源进行调整
#define MAX_MSG_BODY_LEN (1024 * 1024 * 4)

// 消息类型
#define MSG_TYPE_AUTH_REQUEST 0x01               // 认证请求
#define MSG_TYPE_AUTH_RESPONSE 0x02              // 认证响应
#define MSG_TYPE_REGISTER_REQUEST 0x03           // 注册请求
#define MSG_TYPE_REGISTER_RESPONSE 0x04          // 注册响应
#define MSG_TYPE_KEY_EXCHANGE 0x05               // 密钥交换
#define MSG_TYPE_FILE_LIST_REQUEST 0x06          // 文件列表请求
#define MSG_TYPE_FILE_LIST_RESPONSE 0x07         // 文件列表响应
#define MSG_TYPE_FILE_UPLOAD_REQUEST 0x08        // 文件上传请求
#define MSG_TYPE_FILE_UPLOAD_RESPONSE 0x09       // 文件上传响应
#define MSG_TYPE_FILE_UPLOAD_DATA 0x0A           // 文件上传数据
#define MSG_TYPE_FILE_UPLOAD_DATA_RESPONSE 0x0B  // 文件上传数据响应
#define MSG_TYPE_FILE_DOWNLOAD_REQUEST 0x0C      // 文件下载请求
#define MSG_TYPE_FILE_DOWNLOAD_RESPONSE 0x0D     // 文件下载响应
#define MSG_TYPE_FILE_DOWNLOAD_DATA 0x0E         // 文件下载数据
#define MSG_TYPE_FILE_DOWNLOAD_ACK 0x0F          // 文件下载确认
#define MSG_TYPE_FILE_DELETE_REQUEST 0x10        // 文件删除请求
#define MSG_TYPE_FILE_DELETE_RESPONSE 0x11       // 文件删除响应
#define MSG_TYPE_FILE_DOWNLOAD_DATA_REQUEST 0x12 // 文件下载数据请求 (新)
#define MSG_TYPE_TRANSFER_CANCEL_REQUEST 0x13    // 取消传输请求 (新)
#define MSG_TYPE_TRANSFER_CANCEL_RESPONSE 0x14   // 取消传输响应 (新)
#define MSG_TYPE_ERROR 0xFF                      // 错误消息

// 传输类型
#define TRANSFER_TYPE_UPLOAD 0x01   // 上传传输
#define TRANSFER_TYPE_DOWNLOAD 0x02 // 下载传输

// 错误码
#define ERR_SUCCESS 0x00              // 成功
#define ERR_AUTH_FAILED 0x05          // 认证失败
#define ERR_FILE_NOT_FOUND 0x02       // 文件不存在
#define ERR_PERMISSION_DENIED 0x03    // 权限不足
#define ERR_DISK_FULL 0x04            // 磁盘已满
#define ERR_INTERNAL_ERROR 0x06       // 内部错误
#define ERR_CRYPTO_ERROR 0x07         // 加密错误
#define ERR_CONNECTION_ERROR 0x08     // 连接错误
#define ERR_PROTOCOL_VERSION 0x09     // 协议版本不兼容
#define ERR_BUSY 0x0A                 // 服务器忙碌 (例如，正在进行其他上传)
#define ERR_INVALID_STATE 0x0B        // 无效状态 (例如，在没有进行上传时收到上传数据)
#define ERR_INVALID_PATH 0x0C         // 无效的路径或文件名 (例如，尝试删除 "." 或 "..")
#define ERR_FILE_TOO_LARGE 0x0D       // 文件过大 (Value 13)
#define ERR_INVALID_REQUEST 0x0E      // 无效请求 (New Value 14)
#define ERR_RECV_WOULD_BLOCK 0x0F     // recv would block on non-blocking socket (New Value 15)
#define ERR_NOT_AUTHENTICATED 0x10    // 用户未认证 (New Value 16)
#define ERR_UPLOAD_IN_PROGRESS 0x11   // 上传已在进行中 (New Value 17)
#define ERR_DOWNLOAD_IN_PROGRESS 0x12 // 下载已在进行中 (New Value 18)
#define ERR_ACCESS_DENIED 0x13        // 访问被拒绝 (New Value 19, distinct from permission denied for now)
#define ERR_UNKNOWN 0xFF              // 未知错误

#define DOWNLOAD_BLOCK_PLAINTEXT_SIZE 4000 // 客户端请求的明文数据块大小

// 协议头格式（所有消息通用）
typedef struct
{
    uint8_t version; // 协议版本号
    uint8_t type;    // 消息类型
    uint16_t seq;    // 序列号（用于匹配请求和响应）
    uint32_t length; // 消息体长度
    uint32_t crc32;  // 消息完整性校验
} __attribute__((packed)) message_header_t;

// 认证请求消息
typedef struct
{
    char username[32]; // 用户名
    char password[64]; // 密码（实际传输加密后的哈希值）
} __attribute__((packed)) auth_request_t;

// 认证响应消息
typedef struct
{
    uint8_t result;    // 认证结果：0成功，非0失败
    uint32_t user_id;  // 用户ID
    uint8_t token[32]; // 会话令牌
} __attribute__((packed)) auth_response_t;

#define AUTH_USERNAME_LEN 64
#define AUTH_PASSWORD_HASH_LEN 32 // SM3_DIGEST_LENGTH
#define SALT_LENGTH 16            // Or 32, ensure it matches usage in sm3_auth.c and client/server

// 注册请求 (0x03)
typedef struct
{
    char username[AUTH_USERNAME_LEN];
    unsigned char password[AUTH_PASSWORD_HASH_LEN]; // Salted password hash
    unsigned char salt[SALT_LENGTH];                // The salt used for hashing the password
} __attribute__((packed)) register_request_t;

// 注册响应 (0x04)
typedef struct
{
    uint8_t result;   // 0 for success, other for error code
    uint32_t user_id; // User ID if registration is successful (optional, can be 0 if not needed immediately)
} __attribute__((packed)) register_response_t;

// 密钥交换消息（重命名以避免与crypto/sm2_keyex.h中的结构体冲突）
typedef struct
{
    uint8_t public_key_x[32]; // SM2公钥X坐标
    uint8_t public_key_y[32]; // SM2公钥Y坐标
} __attribute__((packed)) protocol_key_exchange_t;

// 文件列表请求消息
typedef struct
{
    char path[256];    // 请求的目录路径
    uint8_t token[32]; // 会话令牌
} __attribute__((packed)) file_list_request_t;

// 文件条目
typedef struct
{
    char name[256];               // 文件名
    uint8_t is_dir;               // 是否为目录
    uint64_t size;                // 文件大小（字节）
    uint64_t modified_time;       // 修改时间
    uint8_t has_read_permission;  // 是否有读权限
    uint8_t has_write_permission; // 是否有写权限
} __attribute__((packed)) file_entry_t;

// 文件上传请求消息
typedef struct
{
    char path[256];    // 目标路径（包含文件名）
    uint64_t size;     // 文件大小
    uint8_t token[32]; // 会话令牌
} __attribute__((packed)) file_upload_request_t;

// 文件上传响应消息
typedef struct
{
    uint8_t result;      // 上传结果：0成功，非0失败
    uint32_t upload_id;  // 上传会话ID
    uint32_t block_size; // 建议的块大小
} __attribute__((packed)) file_upload_response_t;

// 文件上传数据块 (C -> S)
// 客户端发送给服务器的文件数据块
// upload_id: 当前上传操作的唯一标识符 (目前可简化，用一个虚拟值)
// block_seq: 数据块的序列号，用于确保数据按顺序重组 (从0开始，可用于重传等)
// data_len:  实际数据内容的长度 (不包括 upload_id 和 block_seq 的大小)
// data:      文件数据本身
typedef struct
{
    uint32_t upload_id;   // 上传会话ID (目前虚拟)
    uint32_t block_seq;   // 数据块序号 (从0开始)
    uint32_t data_len;    // 当前数据块中有效数据的长度
    unsigned char data[]; // 柔性数组成员，实际数据紧随其后
} file_upload_data_t;

// 文件上传数据块响应 (S -> C)
// 服务器发送给客户端，确认已收到某个数据块
// upload_id: 对应上传操作的唯一标识符
// block_seq: 服务器确认已收到的数据块序列号
// result:    处理结果，0 表示成功，其他表示错误代码 (可复用 ERR_XXX 系列)
typedef struct
{
    uint32_t upload_id; // 上传会话ID
    uint32_t block_seq; // 确认的数据块序号
    uint8_t result;     // 0 = ERR_SUCCESS, 其他 = 错误代码
} file_upload_data_response_t;

// 文件下载请求消息
typedef struct
{
    char path[256];    // 文件路径
    uint8_t token[32]; // 会话令牌
} __attribute__((packed)) file_download_request_t;

// 文件下载响应消息
typedef struct
{
    uint8_t result;       // 下载结果：0成功，非0失败
    uint32_t download_id; // 下载会话ID
    uint64_t size;        // 文件总大小
    uint32_t block_size;  // 块大小
} __attribute__((packed)) file_download_response_t;

// 文件下载数据请求消息 (C -> S)
typedef struct
{
    uint32_t download_id; // 下载会话ID (由服务器在DOWNLOAD_RESPONSE中提供)
    uint32_t block_num;   // 请求的数据块序号 (从0开始)
    // uint8_t token[32]; // 可选：会话令牌 (为简化，暂时不加)
} __attribute__((packed)) file_download_data_request_t;

// 文件下载数据消息
typedef struct
{
    uint32_t download_id; // 下载会话ID
    uint32_t block_num;   // 块序号
    uint32_t data_len;    // 数据长度
    uint8_t is_last;      // 是否为最后一块
    unsigned char data[]; // ADDED: Flexible array member for actual data
} __attribute__((packed)) file_download_data_t;

// 文件下载确认消息
typedef struct
{
    uint32_t download_id; // 下载会话ID
    uint32_t block_num;   // 已接收的块序号
    uint8_t result;       // 结果：0成功，非0失败
} __attribute__((packed)) file_download_ack_t;

// 文件删除请求消息
typedef struct
{
    char path[256];    // 文件路径
    uint8_t token[32]; // 会话令牌
} __attribute__((packed)) file_delete_request_t;

// 文件删除响应消息
typedef struct
{
    uint8_t result; // 删除结果：0成功，非0失败
} __attribute__((packed)) file_delete_response_t;

// 错误消息
typedef struct
{
    uint8_t code;      // 错误代码
    char message[256]; // 错误描述
} __attribute__((packed)) error_message_t;

// 取消传输请求消息
typedef struct
{
    uint32_t transfer_id; // 传输ID (上传ID或下载ID)
    uint8_t type;         // 传输类型：1=上传，2=下载
} __attribute__((packed)) transfer_cancel_request_t;

// 取消传输响应消息
typedef struct
{
    uint32_t transfer_id; // 传输ID
    uint8_t result;       // 结果：0成功，非0失败
} __attribute__((packed)) transfer_cancel_response_t;

// 发送消息
int send_message(int sock, uint8_t type, uint16_t seq, const void *data, uint32_t len);

// 接收消息
int recv_message(int sock, uint8_t *type, uint16_t *seq, void **data, uint32_t *len);

// 接收特定类型的消息
int recv_specific_message(int sock, uint8_t expected_type, uint16_t expected_seq, void **data, uint32_t *len);

// 发送错误消息
int send_error_message(int sock, uint16_t seq, uint8_t error_code, const char *error_msg);

// 计算CRC32校验和
uint32_t calculate_crc32(const void *data, size_t len);

#endif /* PROTOCOL_H */